<template>
  <!-- 文章详情 -->
  <div class="article-detail">
    <SkeletonLoading v-if="skeletionHide" />

    <div class="view" v-else>
      <!-- 文章头部信息 -->
      <div class="article-header">
        <motion.div :style="scrollIndicator"></motion.div>
        <h1 class="title">{{ article.title }}</h1>
        <div class="meta">
          <span class="time">
            <img
              src="https://vue-wj.oss-cn-beijing.aliyuncs.com/icon/日历.png"
            />
            <span>{{ article.createTime }}</span>
          </span>
          <!-- 标签 -->
          <span class="category">
            <div class="label" v-for="item in article.tags" :key="item.id">
              <img
                src="https://vue-wj.oss-cn-beijing.aliyuncs.com/icon/%E6%A0%87%E7%AD%BE_1.png"
              />
              <span>{{ item.name }}</span>
            </div>
          </span>
        </div>
      </div>

      <!-- Markdown内容区域 -->
      <div class="article-content" v-html="article.content" v-highlight></div>

      <!-- 点赞功能区域 -->
      <div class="user-like">
        <div class="desc">喜欢的话就点个赞吧😀</div>
        <div class="like" @click="userAddLike">
          <img
            src="https://vue-wj.oss-cn-beijing.aliyuncs.com/icon/%E5%96%9C%E6%AC%A2.png"
            alt="点赞"
          />
        </div>
        <div class="count">
          {{ article.likeCount }}
        </div>
      </div>

      <!-- 评论区域 -->
      <div class="comment" ref="commentRef">
        <div class="c-title">发表评论</div>
        <div class="form">
          <el-form
            :inline="true"
            ref="formRef"
            :model="commentQuery"
            :rules="rules"
          >
            <el-form-item label="邮箱" prop="userEmail">
              <el-input
                type="email"
                placeholder="请输入邮箱"
                v-model="commentQuery.userEmail"
              ></el-input>
            </el-form-item>
            <el-form-item label="昵称" prop="username">
              <el-input
                placeholder="请输入昵称"
                v-model="commentQuery.username"
              ></el-input>
            </el-form-item>
            <el-form-item label="头像" class="avatar">
              <el-upload
                v-model:file-list="successImgArr"
                :action="serverUploadImg"
                list-type="picture"
                :on-success="handleSuccess"
                :on-preview="handlePreview"
                :on-remove="handleRemove"
                :on-error="handleError"
                :on-exceed="handleExceed"
                :limit="1"
              >
                <el-button type="primary">选择</el-button>
                <template #tip>
                  <div class="el-upload__tip">可选择上传,否则将系统默认</div>
                </template>
              </el-upload>
            </el-form-item>
            <el-form-item class="input-comment">
              <el-input
                v-model="commentQuery.content"
                type="textarea"
                placeholder="发表您的评论吧!"
                class="textarea"
                maxlength="500"
                show-word-limit
                :rows="7"
                :autosize="{ minRows: 7, maxRows: 8 }"
              >
              </el-input>
              <el-button @click="submitComment">发送</el-button>
            </el-form-item>
          </el-form>
        </div>

        <div class="comment-list" v-for="item in commentList" :key="item.id">
          <div class="item">
            <div class="first-comment">
              <div class="head">
                <div class="url">
                  <el-avatar
                    :src="item.headerUrl"
                    style="width: 30px; height: 30px"
                  ></el-avatar>
                </div>
                <div class="username">
                  {{ item.username }}
                </div>
                <div class="create-time">{{ item.createTime }}</div>
              </div>
              <div class="content">{{ item.content }}</div>
            </div>
            <div
              class="replise-comment"
              v-for="reply in item.replyComments || []"
              :key="reply.id"
            >
              <div class="r-item">
                <div class="r-head">
                  <div class="r-url">
                    <el-avatar
                      src="https://butvan-blog.oss-cn-beijing.aliyuncs.com/7e992325-2f76-42a8-a087-637489bf7acc.jpeg"
                      style="width: 30px; height: 30px"
                    ></el-avatar>
                  </div>
                  <div class="username">{{ reply.username }}</div>
                  <div class="create-time">{{ reply.createTime }}</div>
                </div>
                <div class="r-content">{{ reply.content }}</div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <el-dialog v-model="userSignDialogHide" width="470">
    <UserSign />
  </el-dialog>
</template>

<script setup>
import { ref, onMounted } from "vue";
import { useRoute } from "vue-router";
import {
  getArticleByIdService,
  getArticleCommentService,
  userAddArticelCommentService,
  userAddArticleLikeService,
} from "@/api/Articles";
import { useIntersectionObserver } from "@vueuse/core";
import { ElMessage } from "element-plus";
import {
  getLocalToUserInfo,
  setUserInfoLocalStorage,
} from "@/utils/UserInfoStore";
import { serverStore } from "@/stores/server";
import UserSign from "@/components/UserSign.vue";
import { motion, useScroll } from "motion-v";
import SkeletonLoading from "@/components/SkeletonLoading.vue";
import { setUserNameWithUserEmail } from "../../utils/UserInfoStore";
import { closeWebLoading, showWebLoading } from "@/utils/loadingUtils";

const skeletionHide = ref(true);

const { scrollYProgress } = useScroll();

const scrollIndicator = {
  scaleX: scrollYProgress,
  position: "fixed",
  top: 0,
  left: 0,
  right: 0,
  height: "1px",
  originX: 0,
  backgroundColor: "#ff0088",
  zIndex: 99999,
};

// 服务端上传图片地址
const { serverUploadImg } = serverStore();
// 从路由获取文章ID
const route = useRoute();
const articleId = route.params.id;
// 当前用户id
const userId = localStorage.getItem("ButVanUserId");

const article = ref({}); // 初始化文章详情数据用于接收后端返回数据

// 调取后端接口获取文章详情的数据
const getArticleService = async (id) => {
  await getArticleByIdService(id).then(({ data }) => {
    article.value = data;
    skeletionHide.value = false;
  });
};

// 评论表单
const commentQuery = ref({
  id: articleId,
  userEmail: "",
  username: "",
  headerUrl: "",
  content: "",
});
const formRef = ref();
// 表单那验证
const rules = {
  userEmail: [
    {
      required: true,
      message: "请输入邮箱",
      trigger: "blur",
    },
    {
      type: "email",
      message: "请输入正确的邮箱格式",
      trigger: "blur",
    },
  ],
  username: [
    {
      required: true,
      message: "请输入昵称",
      trigger: "blur",
    },
    {
      min: 2,
      max: 20,
      message: "昵称长度需在2 - 20个字符之间",
      trigger: "blur",
    },
  ],
};
// 上传头像的回调数据
const successImgArr = ref([]);
// 上传成功的回调函数
const handleSuccess = () => {
  ElMessage.success("上传成功");
  commentQuery.value.headerUrl = successImgArr.value[0].response.msg;
};
// 点击上传列表图片
const handlePreview = (file) => {
  console.log("列表", file);
};
// 移除出列表图片
const handleRemove = () => {
  ElMessage.success("移除图片");
  console.log("移除图片");
};
const handleError = () => {
  ElMessage.error("图片上传失败");
};
const handleExceed = () => {
  ElMessage.warning("超出上传图片上限");
};
/**
 * 发表评论
 */
const submitComment = () => {
  formRef.value.validate((valid) => {
    if (valid) {
      // 表单验证通过执行
      if (commentQuery.value.content === "") {
        ElMessage.error("评论内容不能是空");
        return false;
      } else {
        if (commentQuery.value.id === null) {
          ElMessage.error("请刷新后重试");
          return false;
        }
        const loading = showWebLoading();
        userAddArticelCommentService(commentQuery.value).then((res) => {
          setUserInfoLocalStorage(res.data);
          const nameWithEmail = {
            username: commentQuery.value.username,
            userEmail: commentQuery.value.userEmail,
          };
          setUserNameWithUserEmail(nameWithEmail);
          closeWebLoading(loading);
          getCommentList(articleId);
          commentQuery.value = {
            id: articleId,
            userEmail: "",
            username: "",
            headerUrl: "",
            content: "",
          };
          successImgArr.value = [];
        });
      }
    }
  });
};

const userSignDialogHide = ref(false);

/**
 * 用户点赞文章
 */
const userAddLike = () => {
  // 判断本地存储中是否有用户id
  if (userId) {
    userAddArticleLikeService(articleId).then(() => {
      getArticleService(articleId);
    });
  } else {
    ElMessage.warning("您还没有登录哦");
    // 打开用户注册框
    userSignDialogHide.value = true;
  }
};

/**
 * 获取评论对应评论内容数据
 */
const commentList = ref([]);
const commentRef = ref(null);
const getCommentList = async (id) => {
  const { data } = await getArticleCommentService(id);
  commentList.value = data;
};

/**
 * 判断元素是否进入视口区域在发送请求执行
 */
setTimeout(() => {
  const { stop } = useIntersectionObserver(
    commentRef,
    ([{ isIntersecting }]) => {
      if (isIntersecting) {
        getCommentList(articleId).then(() => {
          stop();
        });
      }
    }
  );
}, 1000);

const getLocaluserNameWithEmail = () => {
  const obj = getLocalToUserInfo();
  if (obj) {
    commentQuery.value.userEmail = obj.userEmail || "";
    commentQuery.value.username = obj.username || "";
  }
};

onMounted(() => {
  getArticleService(articleId);
  getLocaluserNameWithEmail();
  window.scrollTo(0, 0);
});
</script>

<style lang="scss" scoped>
.article-detail {
  min-height: 100vh;
  max-width: 900px;
  margin: 0 auto;
  padding: 24px;
  background: rgb(255, 255, 255, 0.7);
  border-radius: 0px 0px 12px 12px;
  box-shadow: 0 2px 7px rgba(0, 0, 0, 0.08);

  .article-header {
    margin-bottom: 24px;
    padding-bottom: 16px;
    border-bottom: 1px solid #eee;

    .title {
      font-size: 28px;
      font-weight: bold;
      color: #2c3e50;
      margin-bottom: 16px;
    }

    .meta {
      display: flex;
      align-items: center;
      flex-wrap: wrap;
      gap: 16px;
      color: #666;

      .time {
        flex-basis: auto;
        display: flex;
        align-items: center;
        gap: 4px;

        img {
          width: 16px;
          height: 16px;
        }
      }

      .category {
        flex-basis: auto;
        display: flex;
        margin-left: 10px;
        .label {
          display: flex;
          gap: 6px;
          margin-right: 5px;
          img {
            width: 21px;
          }
          span {
            font-size: 14px;
          }
        }
      }
    }
  }

  .article-content {
    color: #2c3e50;

    :deep(h1, h2, h3, h4, h5, h6) {
      margin: 42px 0;
    }

    :deep(p) {
      line-height: 2.2;
    }

    :deep(code) {
      border-radius: 7px;
      padding: 30px;
    }

    :deep(pre) {
      position: relative;
      margin: 20px 0px;
      padding: 12px 0;
      overflow-x: auto;
      white-space: pre;
      tab-size: 4;
    }

    :deep(.code-lang) {
      position: absolute;
      top: 18px;
      left: 10px;
      color: #8dceec;
      padding: 2px 6px;
      border-radius: 2px;
      font-size: 14px;
      font-weight: 600;
      z-index: 1;
    }
  }

  .user-like {
    margin: 36px 0px;
    display: flex;
    align-items: center;
    gap: 15px;

    .desc {
      font-weight: 600;
      color: #f0bc5c;
    }

    .like {
      cursor: pointer;

      img {
        transition: all 0.3s;
        width: 26px;
        height: 26px;
        border-radius: 50%;
      }

      :hover {
        transform: scale(1.5);
        box-shadow: 0px 2px 15px #e67e5e;
      }
    }
  }

  .comment {
    margin-top: 36px;
    min-height: 20vh;

    .c-title {
      margin: 36px 0px;
      font-weight: 600;
      font-size: 22px;
    }

    .form {
      .textarea {
        width: 45vw;
        @media (max-width: 768px) {
          width: 85vw;
        }
      }

      .avatar {
        :deep(.el-button) {
          margin-left: 10px;
          height: 3vh;
          color: #3bafdd;
          background-color: #d5edf0c0;
          border-color: #c7e9e7;
        }
      }

      .input-comment {
        :deep(.textarea textarea) {
          position: relative;
          resize: none;
        }

        :deep(.el-button) {
          position: absolute;
          top: 55%;
          right: 5px;
          border: none;
          color: #3bafdd;
          background-color: #d5edf0c0;
          border-radius: 0.5rem;
        }
      }
    }

    .comment-list {
      margin: 10px 0px;
      .item {
        min-height: 10vh;
        .first-comment {
          width: 20vw;
          min-height: 10vh;

          @media (max-width: 768px) {
            width: 230px;
          }

          .head {
            display: flex;
            align-items: center;
            gap: 15px;

            .create-time {
              font-size: 15px;
              color: #848485;
            }
          }

          .content {
            padding: 15px 15px;
            min-height: 7vh;
            background-color: #b2d8e7a2;
            color: #525758;
            border-radius: 0px 12px 12px 12px;
            border: 0.7px solid #6cbfe9;
          }
        }

        .replise-comment {
          min-height: 10vh;
          @media (max-width: 768px) {
            width: 90vw;
          }
          .r-item {
            margin-left: 30%;
            width: 50%;
            @media (max-width: 768px) {
              margin-left: 40%;
            }
            .r-head {
              display: flex;
              align-items: center;
              gap: 15px;

              .create-time {
                font-size: 15px;
                color: #848485;
              }
            }

            .r-content {
              padding: 15px 15px;
              min-height: 7vh;
              background-color: #b2d8e7a2;
              color: #525758;
              border-radius: 0px 12px 12px 12px;
              border: 0.7px solid #6cbfe9;
            }
          }
        }
      }
    }
  }
}

@media (max-width: 768px) {
  .article-detail {
    .meta {
      .category {
        margin-left: 0 !important;
      }
    }
  }
}
</style>